package ms.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

import ms.jasim.model.CustomizableObject;
import ms.jasim.model.JasimModel;
import ms.jasim.model.ModelObject;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;

public class JasimUtils {
	
	@SuppressWarnings("unchecked")
	public static <T extends Serializable> T cloneObject(T obj) {
		ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
        try {
        	ObjectOutputStream out = new ObjectOutputStream(bos);
			out.writeObject(obj);
			out.close();
			ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
			return (T) inputStream.readObject();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void saveJasimModel(JasimModel model, String filename) {
		Resource resource = new XMIResourceImpl(URI.createURI(filename));
		resource.getContents().add(model);
		try {
			resource.save(null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static JasimModel cloneModel(JasimModel source) {
		Resource srcRes = source.eResource();
		if (srcRes == null) {
			srcRes = new XMIResourceImpl();
			srcRes.getContents().add(source);
		}
		Resource tarRes;
		try {
			ByteArrayOutputStream buf = new ByteArrayOutputStream();
			srcRes.save(buf, null);
			
			tarRes = new XMIResourceImpl();
			tarRes.load(new ByteArrayInputStream(buf.toByteArray()), null);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		
		JasimModel result = (JasimModel) tarRes.getContents().get(0);
		result.setURI(result.getURI());
		/*JasimModel result = (JasimModel) EcoreUtil.copy(source);
		for (Goal g: result.getGoals()) {
			Goal sg = source.getGoals().get(g.getName());
			if (sg != null) {
				g.getDecomposition().clear();
				for (Decomposition sde: sg.getDecomposition()) {
					Decomposition de = new DecompositionImpl();
					for (Goal ssg: sde.getSubGoals()) {
						Goal g_sg = result.getGoals().get(ssg.getName());
						if (g_sg != null)
							de.getSubGoals().add(g_sg);
					}
					g.getDecomposition().add(de);
				}
			}
		}*/
		result.getPostProcessCommand().addAll(source.getPostProcessCommand());
		return result;
	}

	public static void setPredefined(ModelObject obj) {
		obj.setPredefined(true);
		for(TreeIterator<EObject> iterator = obj.eAllContents(); iterator.hasNext();) {
			ModelObject subObj = (ModelObject) iterator.next();
			setPredefined(subObj);
		}
		
	}

	public static String toString(Iterator<? extends CustomizableObject> list) {
		StringBuilder sb = new  StringBuilder();
		for(;list.hasNext();) {
			 CustomizableObject object = list.next();
			 sb.append(object.getName());
			 if (object.getText() != object.getName())
				 sb.append('[' + object.getText() + ']');
			 if (list.hasNext())
				 sb.append(", ");
		}
		return sb.toString();
	}

	public static String toString(List<? extends CustomizableObject> list) {
		return toString(list.iterator());
	}
}
